package com.monkey.luffer.springboot.demo.basis.kcc.test.majiang;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.*;

/**
 * @author jiahong.liu
 */
public class Scheduler {
    List<Player> players = new ArrayList<>();
    Map<Player, Seat> playerSeat = new HashMap<>();
    private int zhuangJia = 3;
    private int handOutIndex = 3;
    private boolean hu = false;
    private boolean isPeng = false;
    private Majiang.Card curCard = null;
    Majiang majiang = new Majiang();

    public Scheduler(int robotNum, String name) throws Exception {
        if (robotNum > 4) {
            throw new Exception("非法参数");
        }

        for (int i = 0; i < robotNum; i++) {
            Player robot = new Player("Player" + i);
            players.add(robot);
        }

        for(int i = 0; i < players.size(); i++) {
            playerSeat.put(players.get(i), Seat.getSortByNum(i));
        }

        players.add(new Player(name, true));
    }

    public void begin() throws InterruptedException {
        majiang = new Majiang();
        System.out.println("座位顺序为：");
        System.out.println("庄家为：" + players.get(zhuangJia).name);
        System.out.println("现在开始发牌");
        handOut();
        System.out.println("庄家先出牌：");
        Player.Status status = players.get(handOutIndex).checkIfGetCard(majiang.dealCard(), true);
        handleStatus(status, players.get(handOutIndex), handOutIndex);
        if (hu) {
            return;
        }

        while (true) {
            if(majiang.isEnd()) {
                System.out.println("牌已经发完，对局结束");
                return;
            }


            for(int i = 0; i < players.size(); i++) {
                if (i != handOutIndex) {
                    Player.Status status1 = players.get(i).checkIfGetCard(curCard, false);
                    handleStatus(status1, players.get(i), i);
                }
            }

            if (hu) {
                return;
            }

            if (!isPeng) {
                // 没有peng的则下个人摸牌。
                Seat seat = Seat.getNext(handOutIndex);
                handOutIndex = seat.getSort();
                handleStatus(players.get(handOutIndex).checkIfGetCard(majiang.dealCard(), true),
                        players.get(handOutIndex), handOutIndex);
            } else {
                // 碰了就已经出牌了
                isPeng = false;
            }


        }
    }

    public void handleStatus(Player.Status status, Player player, int index) throws InterruptedException {
        if (Player.Status.HU == status) {
            hu = true;
            handOutIndex = index;
            System.out.println(""  + players.get(handOutIndex).getName() + " 胡牌!,游戏结束");
            System.out.println("手牌为：" + players.get(handOutIndex).getPlayerHand().printCard());
            return;
        }

        if (Player.Status.GANG == status) {
            handOutIndex = index;
            Player.Status newStatus = player.checkIfGetCard(majiang.dealCard(), true);
            handleStatus(newStatus, player, index);
            isPeng = true;
        }

        if (Player.Status.PENG == status) {
            if (player.isManual) {
                curCard = putOutCard(player);
            } else {
                curCard = player.putOutCard(new ArrayList<>(player.getPlayerHand().getAll()));
                handOutIndex = index;
                isPeng = true;
                Thread.sleep(1000);
                System.out.println(""+ player.getName() + "出牌：" + curCard.printCard());
            }

        }

        if (Player.Status.PASS == status) {
            if (handOutIndex == index) {
                if (player.isManual) {
                    curCard = putOutCard(player);
                } else {
                    curCard = player.putOutCard(new ArrayList<>(player.getPlayerHand().getAll()));
                    Thread.sleep(1000);
                    System.out.println(""+ player.getName() + "出牌：" + curCard.printCard());
                }
            }
        }
    }


    private Majiang.Card putOutCard(Player player) {
        System.out.println("您的手牌为: " + player.getPlayerHand().printCard());
        System.out.println("您可以打出一张牌, 输入牌的名字即可");
        Majiang.Card card;
        try {
            Scanner scanner = new Scanner(System.in);
            String line = scanner.nextLine().replace("\n", "");
            card = Majiang.Card.getCard(line.trim());
            if (card == null) {
                throw new Exception("");
            }
            if (!player.hasCard(card)) {
                System.out.println("输入的牌不存在，请按照打印出的牌名重新输入");
                return putOutCard(player);
            }
        } catch (Exception e) {
            System.out.println("输入有误，请重新输入");
            return putOutCard(player);
        }

        player.putOutCard(card);
        return card;
    }

    private void handOut() {
        majiang.shuffle();
        for (int i = 0; i < 4; i++) {
            if (i != 3) {
                for (Player player : players) {
                    player.getPlayerHand().putInCard(majiang.dealCard());
                    player.getPlayerHand().putInCard(majiang.dealCard());
                    player.getPlayerHand().putInCard(majiang.dealCard());
                    player.getPlayerHand().putInCard(majiang.dealCard());
                }
            } else {
                for (Player player : players) {
                    player.getPlayerHand().putInCard(majiang.dealCard());
                }
            }
        }
    }

    @AllArgsConstructor
    @Getter
    public enum Seat {
        /**
         *
         */
        EAST(0),
        SOUTH(1),
        WEST(2),
        NORTH(3),;
        private int sort;

        public static Seat getNext(int cur) {
            for(Seat seat : Seat.values()) {
                if (cur + 1 == seat.getSort()) {
                    return seat;
                }

                if (cur + 1 > 4) {
                    return Seat.EAST;
                }
            }
            return Seat.EAST;
        }

        public static Seat getSortByNum(int cur) {
            for(Seat seat : Seat.values()) {
                if (cur  == seat.getSort()) {
                    return seat;
                }
            }
            return null;
        }
    }
}
